home *** CD-ROM | disk | FTP | other *** search
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include "sha.h"
- #include "rc4.h"
-
- #define BUFFERSIZE 16384
- #define KEYSIZE 20
-
- union SHAKEY
- {
- DWORD keyW [KEYSIZE / sizeof (DWORD)];
- BYTE keyB [KEYSIZE];
- };
-
- typedef struct tagIV
- {
- FILETIME fileTime;
- int rand;
- } IV, *LPIV;
-
- union unionIV
- {
- IV iv;
- BYTE byteIV [sizeof (IV)];
- };
-
-
- // functions
- void LoadIV (HANDLE, LPBYTE);
- BOOL CheckKeyIsValid (LPSTR, LPBYTE);
- void CreateUniqueKey (LPDWORD, LPBYTE, LPIV);
-
- int main (int argc, char *argv[])
- {
- union unionIV iv;
- union SHAKEY key, uniqueKey;
- rc4Key streamKey;
- DWORD nBytesSoFar;
- DWORD nBytesRead, nBytesWritten;
- HANDLE hFile;
- char szFile [_MAX_PATH];
- char szNewFile [_MAX_PATH];
- char szPass [_MAX_PATH];
- BYTE lpFileBuffer [BUFFERSIZE];
-
- // check parameters
- // must be two parameters
- if (argc != 3)
- {
- printf ("\nInvalid parameters. Command line must be:"
- "\n\tDECRYPT \"<passphrase>\" <filename>"
- "\n e.g.\tDECRYPT \"goggomobile\", C:\\TEMP\\TEST.TXT.$#!\n");
- return 1;
- }
- // get passphrase and filename
- lstrcpy (szPass, argv[1]);
- lstrcpy (szFile, argv[2]);
-
- // check for validity of passphrase
- if (!CheckKeyIsValid (szPass, key.keyB))
- return 1;
-
- // open the file
- hFile = CreateFile (szFile,
- GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (hFile == INVALID_HANDLE_VALUE)
- {
- printf ("\nError opening %s\n", szFile);
- return 1;
- }
-
- // Load the iv
- LoadIV (hFile, iv.byteIV);
-
- // use the iv to create a unique key for this file
- CreateUniqueKey (uniqueKey.keyW, key.keyB, &(iv.iv));
-
- // do RC4 setup
- rc4Setup (uniqueKey.keyB, KEYSIZE, &streamKey);
-
- // decrypt the file
- nBytesSoFar = 0;
- do
- {
- // fill the buffer from the file
- ReadFile (hFile, lpFileBuffer, BUFFERSIZE, &nBytesRead, NULL);
- if (nBytesRead)
- {
- // encrypt or decrypt as required
- rc4 (lpFileBuffer, nBytesRead, &streamKey);
- // reset the file pointer for the write
- SetFilePointer (hFile,
- nBytesSoFar, // offset into file
- NULL, // only using files < 2^32 in size
- FILE_BEGIN); // starting point for offset
- // write the buffer
- WriteFile (hFile, lpFileBuffer, nBytesRead,
- &nBytesWritten, NULL);
- // increment byte count
- nBytesSoFar += nBytesRead;
- }
- } while (nBytesRead);
-
- // close the file
- CloseHandle (hFile);
- // rename the file to remove the encryption extension
- lstrcpyn (szNewFile, szFile, lstrlen (szFile) - 3);
- MoveFile (szFile, szNewFile);
- // finish
- return 0;
- }
-
-
- void
- LoadIV (HANDLE hFile, LPBYTE ivAsBytes)
- {
- DWORD nBytesRead;
-
- // set the pointer to the beginning of the iv
- SetFilePointer (hFile, 0-(sizeof(IV)+KEYSIZE), NULL, FILE_END);
-
- // read the iv
- ReadFile (hFile, ivAsBytes, sizeof (IV), &nBytesRead, NULL);
-
- // set the pointer to the last real byte in the file
- SetFilePointer (hFile, 0-(sizeof(IV)+KEYSIZE), NULL, FILE_END);
-
- // set the new EOF
- SetEndOfFile (hFile);
-
- // reset file pointer to the beginning of the file
- SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
-
- return;
- }
-
-
- BOOL
- CheckKeyIsValid (LPSTR szPass, LPBYTE lpKey)
- {
- LONG dwErrorCode;
- DWORD dwSize;
- HKEY hKey;
- union SHAKEY hashedKey, testKey;
- char szKey [KEYSIZE*2+1];
- char szTemp [_MAX_PATH+KEYSIZE+1];
-
- // open the app key
- dwErrorCode = RegOpenKeyEx (HKEY_CURRENT_USER,
- "Software\\Cryptext\\Configuration",
- 0,
- KEY_ALL_ACCESS,
- &hKey);
-
- // succeeded?
- if (dwErrorCode != ERROR_SUCCESS)
- {
- printf ("\nPassword checksum not found in registry\n");
- return FALSE;
- }
- else
- {
- // get the hashed encryption key from the registry
- dwSize = KEYSIZE;
- dwErrorCode = RegQueryValueEx (hKey,
- "HashedKey",
- NULL,
- NULL,
- hashedKey.keyB,
- &dwSize);
-
- // close the registry key
- RegCloseKey (hKey);
- }
-
- // encryption key not found or key not 160 bits long
- if (dwErrorCode != ERROR_SUCCESS || dwSize != KEYSIZE)
- {
- printf ("\nPassword checksum not found or invalid\n");
- return FALSE;
- }
-
- sha_memory ((LPBYTE)szPass, lstrlen (szPass), testKey.keyW);
-
- // copy the key
- CopyMemory (lpKey, testKey.keyB, KEYSIZE);
-
- // convert it to ASCII representation
- wsprintf (szKey, "%08lx%08lx%08lx%08lx%08lx",
- testKey.keyW[0], testKey.keyW[1], testKey.keyW[2], testKey.keyW[3], testKey.keyW[4]);
-
- // add the hash to the password
- wsprintf (szTemp, "%s%s", szPass, szKey);
-
- // hash again
- sha_memory ((LPBYTE)szTemp, lstrlen (szTemp), testKey.keyW);
-
- // now verify against the stored hashed key
- if (hashedKey.keyW[0] != testKey.keyW[0] ||
- hashedKey.keyW[1] != testKey.keyW[1] ||
- hashedKey.keyW[2] != testKey.keyW[2] ||
- hashedKey.keyW[3] != testKey.keyW[3] ||
- hashedKey.keyW[4] != testKey.keyW[4])
- {
- printf ("\nInvalid passphrase\n");
- return FALSE;
- }
-
- return TRUE;
- }
-
-
- void
- CreateUniqueKey (LPDWORD uniqueKey, LPBYTE lpKey, LPIV lpiv)
- {
- BYTE buffer [KEYSIZE + sizeof (IV)];
-
- // copy hash of passphrase
- CopyMemory (buffer, lpKey, KEYSIZE);
- // copy date/time
- CopyMemory (buffer+KEYSIZE, lpiv, sizeof (IV));
- // hash to create key for rc4
- sha_memory (buffer, KEYSIZE + sizeof (IV), uniqueKey);
- }
-